Computer operating systems provide various services to the application programs that execute under the control of the operating system. These services facilitate use of the computer resources. For example, a system routine may provide services to control the writing of data to a printer. A program that wants to print issues a system call to the print routine specifying the data to print. The system print routine controls the details of ensuring that the specified data is printed. Another service that operating systems provide is the allocation of the computer resources (e.g., processor time and memory) among various tasks (programs). One example of resource allocation is multitasking. A multitasking operating system stores several tasks in memory. The operating system allocates one task to use the processor for awhile, then another task, and so on. Thus, there are multiple tasks in various stages of execution which cooperatively share the processor under the control of the operating system.
A primary requirement of a multitasking operating system is to provide a robust and secure operating environment for each task. Each task executes as if it is the only task currently executing on the computer. The operating system must ensure that one task cannot unintentionally or intentionally affect the execution of another task without permission from the other task. To ensure that one task will not affect the execution of another task, an operating system typically ensures that one task does not have access to memory allocated to another task or the operating system. Computers typically provide memory protection hardware to assist in controlling access to memory.
Some microprocessors, such as the Intel 80386 microprocessor, provide memory protection that is integrated with their addressing architecture. FIG. 1 shows an overview of the addressing architecture of the Intel 80386 microprocessor. The addressing architecture uses both a segmentation and paging scheme. Programs specify addresses in a virtual address space. Virtual addresses are segmented and contain a 16-bit segment selector 101 and a 32-bit offset 102. The segmentation system 103 maps virtual addresses to 32-bit linear addresses 104. The paging system 105 then maps linear addresses to 32-bit physical addresses 106. The physical addresses are sent to memory to effect the addressing of a memory location.
FIG. 2 shows the segmentation system of the 80386 which maps a virtual address to a linear address. The virtual address has a segment selector 201 and an offset 202. The segment selector 201 contains an index into a segment descriptor table 203. The segment descriptor table, which is stored in memory, contains an entry for each segment currently defined. A segment is a logically contiguous area of memory. The segment descriptor table entries contain a 32-bit segment base address 204, a 32-bit segment limit 205, and an attributes field 206. The segment base address 204 contains the base address of a segment in the linear address space. The segment limit 205 contains the size of the segment. The attributes field 206 indicates the segment access rights, which include read, write, and execute. A linear address 209 is formed by adding the base segment address 208, which is pointed to by the segment selector 201, to the offset 202. The segmentation system supports memory protection by ensuring that an offset is not larger than the segment limit and that access is consistent with the segment access rights.
The 80386 provides registers for holding segment selectors. The segment registers include the stack segment register (SS), the code segment register (CS), the main data segment register (DS), and three extra segment registers (ES, FS, GS). Virtual addresses are specified by segment register and offset. For example, the virtual address specified as DS:1F1h (the "h" indicating a hexadecimal number) indicates the virtual address formed by the segment selector in the DS register and offset 1F1h. It would increase system overhead if on every memory reference, the segment descriptor table was accessed to retrieve the base address of a segment. To improve performance, the 80386 provides a cache register for each segment register. Each cache register contains the segment descriptor table entry that is indexed by segment selector in the corresponding segment register. FIG. 3 shows the segment registers and the corresponding segment descriptor cache registers. When a segment register is loaded with a segment selector, the processor retrieves an entry from the segment descriptor table using the segment selector as the index and stores the segment base address, the segment limit, and segment attributes in the corresponding segment descriptor cache register. The processor also performs various checks to ensure the integrity of the load. For example, the processor compares the current privilege level with the privilege level of the segment, ensures that the segment descriptor is valid, ensures that the segment type (read, write, execute status) is consistent with the segment register, and ensures that the selector index is within the descriptor table limit. When generating a linear address, the processor retrieves the segment base address from the segment descriptor cache register and adds an offset. Thus, the loading of a segment register is a relatively slow process because of the steps involved in accessing the segment descriptor table (which resides in memory) and loading the segment descriptor cache register. However, the forming of linear addresses occurs quickly because the segment base address is already in the descriptor cache register and can be retrieved quickly.
FIG. 4 shows the paging system of the 80386, which maps a linear address to a physical address. The 32-bit linear address 401 has a 12-bit offset 402 and a 20-bit page table index 403. The 80386 page size is 4K bytes. The page table 404 contains a 32-bit entry for each page defined in the system. (The 80386 actually uses a two-tier page table, but the details are not necessary to understand the present invention.) The entries contain a 12-bit attributes field 406 and a 20-bit page frame address 405. To support memory protection, the attributes field 406 contains a flag indicating whether the page can be accessed when the processor is user or kernel mode (explained below). The page frame address 405 is the base address of the corresponding page in physical memory. The paging system uses the page table index 403 as an index into the page table 404. The physical address 408 is formed with the indexed page frame address 407 in the high order bits and the offset 402 in the low order bits.
The 80386 processor provides privilege levels to help ensure a secure operating environment for each task. The 80386 processor supports four execution privilege levels: 0, 1, 2, and 3. When a task is executing in privilege level 0 (kernel mode), it has access to all the computer resources (e.g., memory and instruction set). Conversely, when a task is executing in privilege level 3 (user mode), it has access to only a limited set of the computer resources.
The 80386 processor provides independent protection controls in both the segmentation and paging systems. The segmentation system includes privilege level, read/write/execute access, and offset limit protection for each segment. The segmentation system ensures that the current privilege level is consistent with the segment privilege level, that the read/write/execute access is consistent with the segment register, and that the offset is less than the limit. The paging system includes privilege level and read/write/execute access protection for each page. The paging system ensures that the current privilege level is consistent with page privilege level and that the read/write/execute access is consistent with the access being attempted.